/**
 * 给一个树，从某个点出发，访问所有的点，求走过的最小距离
 * 首先以1为根，求出如下数据
 * Di：表示以i为起点和终点，访问i子树的最短距离
 * Ui: 表示以i为起点访问i子树并且不回来的最短距离，此时停留点所在的儿子称为小儿子
 * U2[i]: 表示以i为起点访问i子树并且不回来的第二短距离，此时停留点所在的儿子称为二儿子
 * 
 * 再dfs一遍，求出如下数据：
 * Ei: 表示以i为起点和终点，访问所有非i子树节点的最短距离。
 *   显然要先去i的父亲p，然后访问Ep，再然后访问p的其他儿子，代价是Dp - Di
 *   所以 Ei = Ep + Dp - Di
 * Fv： 表示以v为起点，访问所有非v子树节点并且不回来的最短距离
 *   v的父亲记作u，根据最终停留点有三种情况，取最小即可：
 *    1. 停在u的父亲中, 此时 Fv = Du - Dv - w + Fu，即先去p，访问完所有u的其他儿子，然后再去u的父亲，并最终停在那边
 *    2. 停在u的另外的儿子中，且v是u的小儿子，此时 Fv = U2[u] - D[v] - edge.w + E[u]，即先访问u的父亲并且回来，然后访问除了v之外的其他节点并且最终停在u的二儿子处。
 *    3. 停在u的另外的儿子中，且v不是u的小儿子，此时 Fv = U[u] - D[v] - edge.w + E[u]， 即先访问u的父亲并且回来，然后访问除了v之外的其他节点并且最终停在小儿子处
 * 
 * 最后找到 min(Ei + Ui, Fi + Di) 的最小值即可
 * 也就是说，从i点出发，要么先走完非儿子停在儿子处，要么先走完儿子停在非儿子处，并有其一。
 * 
 * 标程其实非常简单。考虑回路，很容易求。现在不是回路，也就是说有一条路径可以减去。
 * 当然要减去最大的路径，因此本质上就是求直径。
 */
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;

using llt = long long;
using vi = vector<int>;
using pii = pair<int, int>;
using vpii = vector<pii>;
using vll = vector<llt>;

template<typename T>
istream & operator >> (istream & is, vector<T> & v){
    for(auto & i : v) is >> i;
    return is;
}

template<typename T>
void input(vector<T> & v, int n){
    v.assign(n + 1, {});
    for(int i=1;i<=n;++i) cin >> v[i];
    return;
}

struct edge_t{
    int from;
    int to;
    llt w;
};

int N;
vector<edge_t> Edges;
vector<vi> G;
vll D, U, U2;
vll F, E;

vector<array<int, 2>> Min;

void dfs(int u, int p){
    llt mine = 0;
    D[u] = 0;
    llt cha = 0;
    llt cha2 = 0;
    for(auto e : G[u]){
        const auto & edge = Edges[e];
        int v = u ^ edge.from ^ edge.to;
        if(v == p) continue;

        dfs(v, u);
        D[u] += D[v] + edge.w + edge.w;
        
        auto tmp = edge.w + edge.w + D[v] - U[v] - edge.w;
        if(cha < tmp) cha2 = cha, cha = tmp, Min[u][1] = Min[u][0], Min[u][0] = v;
        else if(cha2 < tmp) cha2 = tmp, Min[u][1] = v;
    }
    U[u] = D[u] - cha;
    U2[u] = D[u] - cha2;
    return;
}

void dp(int u, int p){
    for(auto e : G[u]){
        const auto & edge = Edges[e];
        int v = u ^ edge.from ^ edge.to;
        if(v == p) continue;

        E[v] = E[u] + D[u] - D[v];
        F[v] = D[u] - D[v] - edge.w + F[u];
        if(v == Min[u][0]) F[v] = min(F[v], U2[u] - D[v] - edge.w + E[u]);
        else F[v] = min(F[v], U[u] - D[v] - edge.w + E[u]);
        dp(v, u);
    }
    return;
}

void work(){
    cin >> N;
    Edges.assign(N, {});
    G.assign(N + 1, {});
    for(int a,b,c,i=1;i<N;++i){
        cin >> Edges[i].from >> Edges[i].to >> Edges[i].w;
        a = Edges[i].from;
        b = Edges[i].to;
        G[a].push_back(i);
        G[b].push_back(i);
    }

    F.assign(N + 1, 0);
    E.assign(N + 1, 0);
    D.assign(N + 1, 0);
    U.assign(N + 1, 0);
    U2.assign(N + 1, 0);
    Min.assign(N + 1, {0, 0});
    int r = 1;
    dfs(r, 0);
    dp(r, 0);
    
    llt ans = -1;
    for(int i=1;i<=N;++i){
        auto t1 = E[i] + U[i];
        auto t2 = D[i] + F[i];
        auto tt = min(t1, t2);
        // cout << i << ": " << tt << endl;
        if(-1 == ans or tt < ans) ans = tt;
    }
    cout << ans << endl;
    return;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int nofkase = 1;
    // cin >> nofkase;
    while(nofkase--) work();
    return 0;
}